package cn.legend.travel.destination.main.service.impl;


import cn.legend.travel.common.enumerator.ServiceCode;
import cn.legend.travel.common.exception.ServiceException;
import cn.legend.travel.common.pojo.po.DistrictSimplePO;
import cn.legend.travel.common.pojo.po.DistrictSimplesPO;
import cn.legend.travel.common.pojo.po.SceneriesPO;
import cn.legend.travel.common.pojo.po.SceneryPO;
import cn.legend.travel.destination.main.dao.cache.repository.IDistrictCacheRepository;
import cn.legend.travel.destination.main.dao.persist.repository.IDistrictRepository;
import cn.legend.travel.destination.main.dao.persist.repository.ISceneryRepository;
import cn.legend.travel.destination.main.dao.search.DestinationElasticsearchRepository;
import cn.legend.travel.destination.main.pojo.vo.DistrictVO;
import cn.legend.travel.destination.main.service.IDistrictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 处理省市区数据的业务实现类
 *
 * @author java@tedu.cn
 * @version 1.0
 */
@Slf4j
@Service
public class DistrictServiceImpl implements IDistrictService {

    @Autowired
    private IDistrictRepository districtRepository;
    @Autowired
    private IDistrictCacheRepository districtCacheRepository;
    @Autowired
    private DestinationElasticsearchRepository repository;
    @Autowired
    private ISceneryRepository sceneryRepository;

    public DistrictServiceImpl() {
        log.debug("创建业务类对象：DistrictServiceImpl");
    }

    @Override
    public List<DistrictSimplesPO>  list() {
        List<DistrictSimplePO> list = districtCacheRepository.list();
        List<DistrictSimplesPO> lists = new ArrayList<>();
        for (DistrictSimplePO districtSimplePO : list) {
            DistrictSimplesPO districtSimplesPO = new DistrictSimplesPO();
            districtSimplesPO.setName(districtSimplePO.getName());
            districtSimplesPO.setList(districtCacheRepository.listByParent(districtSimplePO.getId()));

            lists.add(districtSimplesPO);
        }
        return lists;
    }

    @Override
    public List<DistrictSimplePO> listFromRegion() {
        return districtRepository.listFromRegion();
    }


    @Override
    public SceneriesPO selectByName(String name) {
        Pageable pageable = PageRequest.of(0, 8);
        return selectScenery(name, pageable);
    }

    @Override
    public SceneriesPO selectByNameAndPageable(String name, Integer num) {
        Pageable pageable = PageRequest.of(num-1, 8);
        return selectScenery(name, pageable);
    }

    @Override
    public List<SearchHit<DistrictVO>> selectNearbyAttractions(String name) {
        Pageable pageable = PageRequest.of(0, 20);
        String distance = "200km";
        DistrictVO districtVO = districtRepository.selectListByName(name);
        SearchPage<DistrictVO> searchPage = repository.customSearch(distance,districtVO.getLocation(), pageable);
        SearchHits<DistrictVO> searchHits = searchPage.getSearchHits();
        return searchPage.getContent();
    }

    @Override
    public void rebuildCache() {
        districtCacheRepository.deleteAll();
        Long pId = 0L;
        List<DistrictSimplePO> list = districtRepository.listByParent(pId);

        for (DistrictSimplePO districtSimplePO : list) {
            districtCacheRepository.save(districtSimplePO);
        }

        districtCacheRepository.saveListByParent(pId, list);
        for (DistrictSimplePO listItem : list) {
            callListRecursion(listItem);
        }
    }

    @Override
    public void elasticsearch() {
        repository.deleteAll();
        List<DistrictVO> list = districtRepository.selectAll();
        for (DistrictVO districtVO : list) {
            List<DistrictVO> districtVOS = districtRepository.selectListById(districtVO.getId());
            repository.saveAll(districtVOS);
        }

    }

    /**
     * 递归得到各地区的子级列表数据
     *
     * @param district 地区数据
     */
    private void callListRecursion(DistrictSimplePO district) {
        Long districtId = district.getId();
        List<DistrictSimplePO> list = districtRepository.listByParent(districtId);
        if (!list.isEmpty()) {
            districtCacheRepository.saveListByParent(districtId, list);
            for (DistrictSimplePO districtSimplePO : list) {
                districtCacheRepository.save(districtSimplePO);
                callListRecursion(districtSimplePO);
            }
        }
    }
    private SceneriesPO selectScenery(String name,Pageable pageable){
        Pageable pageable1 = PageRequest.of(0, 8);
        SearchPage<DistrictVO> searchPage = repository.customSearch(name, pageable1);
        List<SearchHit<DistrictVO>> searchHit1 = searchPage.getContent();
        if (searchHit1.isEmpty()){
            String message = "查询失败，请输入正确的关键词";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        SceneriesPO sceneriesPO = new SceneriesPO();
        for (SearchHit<DistrictVO> districtVOSearchHit : searchHit1) {
            DistrictVO content = districtVOSearchHit.getContent();
            List<SceneryPO> sceneryPOList = sceneryRepository.selectByBestinationIds(content.getId(),pageable);
            BeanUtils.copyProperties(content,sceneriesPO);
            sceneriesPO.setList(sceneryPOList);
        }
        return sceneriesPO;
    }
}
